home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr10 / 184_01.zip / YANC.C < prev    next >
Text File  |  1993-06-13  |  24KB  |  1,121 lines

  1. /* YANC version 1.0 -- Yet Another New Catalog program */
  2.  
  3. /* Master disk catalog system */
  4. /* Based on the original catalog programs by Ward Christensen */
  5. /* (FMAP, UCAT, CAT, and QCAT) */
  6. /* and incorporating revisions by Lewis Moseley, Jr. */
  7. /* (NEWCAT and CROSSREF) */
  8. /* Rewritten into a single C program for ease of maintainance. */
  9. /* Menu-driven and extended for ease of use. */
  10.  
  11. /* Written by Ken Presser */
  12. /* Converted to BDS-C by David Welch */
  13. /* 06/15/83, Minor corrections and alterations, J.E. Byram */
  14.  
  15. /* Original C dialect...CW/C from The Code Works */
  16. /* Current C dialect...BDS-C from BD Software */
  17.  
  18. #include "bdscio.h"
  19.  
  20. #define LISTCHAR    5    /* bdos function list char to printer */
  21. #define RETURNVER    12    /* bdos function return version no */
  22. #define RESETDISK    13    /* bdos function reset disk system */
  23. #define SELDISK     14    /* bdos function select disk */
  24. #define SRCHFIRST    17    /* bdos function search for first */
  25. #define SRCHNEXT    18    /* bdos function search for next */
  26. #define DELETEFILE    19    /* bdos function delete file */
  27. #define RENAMEFILE    23    /* bdos function rename file */
  28. #define GETDISK     25    /* bdos function get current disk */
  29. #define SETDMA        26    /* bdos function set dma addr */
  30. #define GETALLOC    27    /* bdos function get addr (alloc) */
  31. #define GETDPB        31    /* bdos function get disk parameter *
  32.                  * block address */
  33. #define FCBSIZE     16    /* cpm directory entry size */
  34. #define NUMDRIVES    16    /* number of cpm drives */
  35. #define DIRSIZ        256    /* max # of cpm dir entries */
  36. #define DMADDR        0x80    /* bdos default dma addr */
  37. #define MAXLINES    60    /* max lines before sending FF */
  38. #define FF        0x0c    /* form feed character */
  39. #define CR        0x0d    /* carriage return character */
  40. #define ESC        0x1b    /* escape */
  41.  
  42. #define YES        TRUE
  43. #define NO        FALSE
  44. #define EOS        NO
  45. #define BOOLEAN     int
  46. #define GETS_SIZE    128
  47. #define UP        0xC1
  48. #define DOWN        0xC2
  49. #define HOME        0xC8
  50.  
  51. int    printer;
  52. char    mdrive,ddrive;
  53. char    *pfcb[DIRSIZ],volname[12],ibuffer[BUFSIZ],obuffer[BUFSIZ];
  54. int    nfcb,cfcb,block,remsz,disksz,dirmax,linecount,itemcount;
  55. struct    dontcat {
  56.         char    fname[13];
  57.         struct    dontcat *next;
  58.         } *dcs;
  59. struct    dontcat *head;
  60.  
  61. main()
  62. {
  63.     int i,cmd;
  64.     char matchstr[GETS_SIZE];
  65.  
  66.     if (bdos(RETURNVER,0) == 0) {
  67.         puts("Can't use this program with CP/M 1.4");
  68.         exit();
  69.         }
  70.     mdrive = 'A';
  71.     ddrive = 'B';
  72.     printer = NO;
  73.     while (1) {
  74.         cmd = menu();
  75.         switch (cmd) {
  76.         case 1: updatedir();
  77.             break;
  78.         case 2: strcpy(matchstr,"*.*");
  79.             listmast(matchstr);
  80.             break;
  81.         case 3: getstr(matchstr);
  82.             listmast(matchstr);
  83.             break;
  84.         case 4: getstr(matchstr);
  85.             listvol(matchstr);
  86.             break;
  87.         case 5: dispdir();
  88.             break;
  89.         case 6: initmast();
  90.             break;
  91.         case 7: getdefaults();
  92.             break;
  93.         case 8: makedirfile();
  94.             break;
  95.         case 9: exit();
  96.             break;
  97.         }
  98.     }
  99. }
  100.  
  101. menu()
  102. {
  103.     char x,y;
  104.     char c;
  105.     int i;
  106.  
  107.     clear();
  108.     gotoxy(29,0);
  109.     printf("Master Catalog System");
  110.     gotoxy(5,2);
  111.     printf("Defaults:  ");
  112.     printf("Master Catalog on drive %c:",mdrive);
  113.     printf("  Disk to Add on drive %c:",ddrive);
  114.     gotoxy(16,3);
  115.     printf("Printer: ");
  116.     if (printer)
  117.         printf("on");
  118.     else    printf("off");
  119.     gotoxy(16,5);
  120.     printf("...use arrow keys to move cursor to selection...");
  121.     gotoxy(17,7); revvid(); putchar(' '); norvid(); gotoxy(21,7);
  122.     printf("1) Update the master catalog with above defaults");
  123.     gotoxy(17,9); revvid(); putchar(' '); norvid(); gotoxy(21,9);
  124.     printf("2) List the entire master catalog");
  125.     gotoxy(17,11); revvid(); putchar(' '); norvid(); gotoxy(21,11);
  126.     printf("3) List specific files with a match key");
  127.     gotoxy(17,13); revvid(); putchar(' '); norvid(); gotoxy(21,13);
  128.     printf("4) List a volume from the master catalog");
  129.     gotoxy(17,15); revvid(); putchar(' '); norvid(); gotoxy(21,15);
  130.     printf("5) List the disk directory");
  131.     gotoxy(17,17); revvid(); putchar(' '); norvid(); gotoxy(21,17);
  132.     printf("6) Initialize MAST.CAT");
  133.     gotoxy(17,19); revvid(); putchar(' '); norvid(); gotoxy(21,19);
  134.     printf("7) Update the defaults");
  135.     gotoxy(17,21); revvid(); putchar(' '); norvid(); gotoxy(21,21);
  136.     printf("8) Make directory volume label file");
  137.     gotoxy(17,23); revvid(); putchar(' '); norvid(); gotoxy(21,23);
  138.     printf("9) Quit this program");
  139.     gotoxy(17,7);
  140.     while (1) {
  141.         c = hinchar();
  142.         switch (c) {
  143.         case UP:    getxy(&x,&y);
  144.                 if (y == 7) break;
  145.                 y = y - 2;
  146.                 gotoxy(x,y);
  147.                 break;
  148.         case DOWN:    getxy(&x,&y);
  149.                 if (y == 23) break;
  150.                 y = y + 2;
  151.                 gotoxy(x,y);
  152.                 break;
  153.         case HOME:    gotoxy(17,7);
  154.                 break;
  155.         case CR:    getxy(&x,&y);
  156.                 clear();
  157.                 x = y/2-2;
  158.                 if ( x<1 || x>9 )
  159.                     abort("Invalid menu response = %d"
  160.                         ,x);
  161.                 return x;
  162.                 break;
  163.         }
  164.     }
  165. }
  166.  
  167. updatedir()
  168. {
  169.     char *top;
  170.  
  171.     top = alloc(1);
  172.     printf("\r\nInsert disk to be cataloged in %c:\r\n",ddrive);
  173.     if (mdrive != ddrive)
  174.         printf("Be sure the master disk is in %c:\r\n",mdrive);
  175.     hold();
  176.     readdir();
  177.     if (strcmp(volname,"n/a"))
  178.         updatemast();
  179.     else {
  180.         printf("No volume label file on disk\r\n");
  181.         hold();
  182.         }
  183.     free(top);
  184. }
  185.  
  186. dispdir()
  187. {
  188.     printf("Load disk to list in drive %c:  ",ddrive);
  189.     hold();
  190.     puts("\r\nReading directory...\r\n\n");
  191.     readdir();
  192.     listdir();
  193. }
  194.  
  195. readdir()
  196. {
  197.     char fcb[FCBSIZE];
  198.     char dmapos;
  199.     BOOLEAN firstime;
  200.     char *alloc;
  201.     char *ptr,bsh;
  202.     int i;
  203.  
  204.     bdos(RESETDISK,0);
  205.     bdos(SELDISK,(ddrive-'A'));
  206.     bdos(SETDMA,DMADDR);
  207.     ptr = bdos(GETDPB,0);
  208.     ptr += 2;
  209.     bsh = *ptr;
  210.     block = 1 << (bsh-3);
  211.     ptr += 3;
  212.     disksz = ((*ptr++)+(*ptr++)*256)*block-block;
  213.     remsz = disksz;
  214.     dirmax = (*ptr+(*(ptr+1)*256))+1;
  215.     firstime = YES;
  216.     for (i=0; i<13; i++)
  217.         fcb[i] = '?';
  218.     for (i=13; i<FCBSIZE; i++)
  219.         fcb[i] = '\0';
  220.     nfcb = 0;
  221.     volname[0] = 'n';
  222.     volname[1] = '/';
  223.     volname[2] = 'a';
  224.     volname[3] = EOS;
  225.     while (1) {
  226.         dmapos = bdos(firstime ? SRCHFIRST : SRCHNEXT,fcb);
  227.         if (dmapos == 255) break;
  228.         firstime = NO;
  229.         remsz -= copyentry(DMADDR + 32*(dmapos%4));
  230.         }
  231. }
  232.  
  233. copyentry(fcb)
  234. char *fcb;
  235. {
  236.     int i,j,val;
  237.     char *ptr;
  238.  
  239.     if ((*fcb < 32) && (*(fcb+1) != '-')) {
  240.         ptr = fcb + 1;
  241.         for (i=0; i<11; i++) {
  242.             *ptr = (*ptr) & 0x7f; 
  243.             ++ptr;
  244.             }
  245.         for (i=0; i<nfcb; i++) {
  246.             val = comparefcb(pfcb[i],fcb);
  247.             switch (val) {
  248.             case -2: break;
  249.             case -1: return copyfcb(i,fcb);
  250.                  break;
  251.             case 0: abort("duplicate directory entry\r\n");
  252.                 break;
  253.             case  1: return (*(fcb+15)/(8*block)*block +
  254.                     ((*(fcb+15)%(8*block)>0)*block));
  255.                  break;
  256.             case  2: for (j=nfcb++; j>i; j--)
  257.                     pfcb[j] = pfcb[j-1];
  258.                  pfcb[i] = alloc(FCBSIZE);
  259.                  return copyfcb(i,fcb);
  260.                  break;
  261.                 }
  262.             }
  263.         i = nfcb++;
  264.         pfcb[i] = alloc(FCBSIZE);
  265.         return copyfcb(i,fcb);
  266.         }
  267.     else if ((*fcb < 32) && (*(fcb+1) == '-')) {
  268.         j = 0;
  269.         for (i=2; i<9; i++)
  270.             volname[j++] = fcb[i];
  271.         volname[j++] = ' ';
  272.         for (i=9; i<12; i++)
  273.             volname[j++] = fcb[i];
  274.         volname[j] = EOS;
  275.         return 0;
  276.         }
  277.     else    return 0;
  278. }
  279.  
  280. copyfcb(ptr,fcb)
  281. char *fcb;
  282. int ptr;
  283. {
  284.     char *tfcb,*sfcb;
  285.     int i;
  286.  
  287.     tfcb = sfcb = pfcb[ptr];
  288.     for (i=0; i<FCBSIZE; i++)
  289.         *tfcb++ = *fcb++;
  290.     return (*(sfcb+15)/(8*block)*block +
  291.         ((*(sfcb+15)%(8*block)>0)*block));
  292. }
  293.  
  294. comparefcb(fcb1,fcb2)
  295. char *fcb1,*fcb2;
  296. /* Compare two fcb's  -- return:            *
  297.  *   -2 name1,user1 < name2,user2            *
  298.  *   -1 name1,user1 = name2,user2 & extent1 < extent2;    *
  299.  *    0 name1,user1,extent1 = name2,user2,extent2;    *
  300.  *   +1 name1,user1 = name2,user2 & extent1 > extent2;    *
  301.  *   +2 name1,user1 > name2,user2;            */
  302.  
  303. {
  304.     char s1[14],s2[14];
  305.     int i,k,val;
  306.  
  307.     for (i=0,k=1; k<12; i++,k++) {
  308.         s1[i] = fcb1[k];
  309.         s2[i] = fcb2[k];
  310.         }
  311.     s1[i] = fcb1[0] + '0';
  312.     s2[i] = fcb2[0] + '0';
  313.     i++;
  314.     s1[i] = EOS;
  315.     s2[i] = EOS;
  316.     val = strcmp(s1,s2);
  317.     if (val < 0)
  318.         return -2;
  319.     else if (val > 0)
  320.         return 2;
  321.     else
  322.         if (fcb1[12] < fcb2[12])
  323.             return -1;
  324.         else if (fcb1[12] > fcb2[12])
  325.             return 1;
  326.         else    return 0;
  327. }
  328.  
  329. listdir()
  330. {
  331.     int i,j,k,size;
  332.     char s[50],stemp[5];
  333.     char *fcb;
  334.     
  335.     sprintf(s,"        Directory for Volume: %s\r\n",volname);
  336.     printf("%s",s);
  337.     if (printer) {
  338.         bdos(LISTCHAR,FF);
  339.         for (i=0; i<strlen(s); i++)
  340.             bdos(LISTCHAR,s[i]);
  341.         }
  342.     for (i=0; i<nfcb; i++) {
  343.         fcb = pfcb[i];
  344.         k = 0;
  345.         s[k++] = ddrive;
  346.         s[k++] = '0' + *fcb++;
  347.         s[k++] = ':';
  348.         for (j=1; j<9; j++)
  349.             if (*fcb == ' ')
  350.                 fcb++;
  351.             else    s[k++] = *fcb++;
  352.         if (*fcb != ' ')
  353.             s[k++] = '.';
  354.         for (j=9; j<12; j++)
  355.             if (*fcb == ' ')
  356.                 fcb++;
  357.             else    s[k++] = *fcb++;
  358.         while (k<16)
  359.             s[k++] = ' ';
  360.         size = *fcb*16 + *(fcb+3)/(8*block)*block +
  361.             ((*(fcb+3)%(8*block)>0)*block);
  362.         sprintf(stemp,"%d",size);
  363.         for (j=0; j<strlen(stemp); j++)
  364.             s[k++] = stemp[j];
  365.         s[k++] = 'K';
  366.         while (k < 21)
  367.             s[k++] = ' ';
  368.         s[k] = EOS;
  369.         if ((i % 3) == 2)
  370.             printf("%s\r\n",s);
  371.         else    printf("%s | ",s);
  372.         if (printer) {
  373.             if ((i % 3) == 0)
  374.                 for (k=0; k<5; k++)
  375.                     bdos(LISTCHAR,' ');
  376.             for (k=0; k<strlen(s); k++)
  377.                 bdos(LISTCHAR,s[k]);
  378.             if ((i % 3) == 2) {
  379.                 bdos(LISTCHAR,'\r');
  380.                 bdos(LISTCHAR,'\n');
  381.                 }
  382.             else {
  383.                 bdos(LISTCHAR,' ');
  384.                 bdos(LISTCHAR,'|');
  385.                 bdos(LISTCHAR,' ');
  386.                 }
  387.             }
  388.         }
  389.     sprintf(s,"\r\n->Drive %c: %d files (%dk free, %dk capacity)\r\n",
  390.         ddrive,nfcb,remsz,disksz);
  391.     printf("%s",s);
  392.     if (printer)
  393.         for (i=0; i<strlen(s); i++)
  394.             bdos(LISTCHAR,s[i]);
  395.     hold();
  396. }
  397.  
  398. updatemast()
  399. {
  400.     char fcb[33];
  401.     char rec[GETS_SIZE],fname[13],rfname[13],rvolname[12];
  402.     int i,ptr,size,rsize,recsize,fc,vc;
  403.  
  404.     if (mdrive == ddrive) {
  405.         printf("Insert master catalog disk in drive %c:\r\n",
  406.             mdrive);
  407.         hold();
  408.         }
  409.     bdos(RESETDISK,0);
  410.     bdos(SELDISK,(mdrive - 'A'));
  411.     bdos(SETDMA,DMADDR);
  412.     strcpy(fcb,"\1MAST    BAK\1\1\1\1");
  413.     for (i=1; i<16; i++)
  414.         if (fcb[i] == '\1')
  415.             fcb[i] = '\0';
  416.     fcb[0] = mdrive - '@';
  417.     bdos(DELETEFILE,fcb);
  418.     strcpy(fcb,"\1MAST    CAT\1\1\1\1\1MAST    BAK\1\1\1\1");
  419.     for (i=1; i<32; i++)
  420.         if (fcb[i] == '\1')
  421.             fcb[i] = '\0';
  422.     fcb[0] = mdrive - '@';
  423.     if (bdos(RENAMEFILE,fcb) == 255) {
  424.         puts("MAST.CAT not on default drive -- ");
  425.         hold();
  426.         return 0;
  427.         }
  428.     if (fopen("MAST.BAK",ibuffer) == ERROR) {
  429.         puts("Can't reopen MAST.BAK -- ");
  430.         hold();
  431.         return 0;
  432.         }
  433.     if (fcreat("MAST.CAT",obuffer) == ERROR) {
  434.         puts("Can't reopen MAST.CAT -- ");
  435.         hold();
  436.         return 0;
  437.         }
  438.     copydont(obuffer,ibuffer);
  439.     cfcb = -1;
  440.     size = bldfree(fname,remsz);
  441.     recsize = readline(ibuffer,rec);
  442.     if (recsize > 0)
  443.         rsize = extract(rfname,rvolname,rec);
  444.     while (recsize >= 0 && cfcb < nfcb) {
  445.         fc = strcmp(fname,rfname);
  446.         vc = strcmp(volname,rvolname);
  447.         if (fc < 0) {
  448.             putentry(obuffer,fname,volname,size);
  449.             printf("ADD:%s\r\n",fname);
  450.             ++cfcb;
  451.             if (cfcb < nfcb)
  452.                 size = bldentry(fname);
  453.             }
  454.         else if (fc == 0) {
  455.             if (vc < 0) {
  456.                 putentry(obuffer,fname,volname,size);
  457.                 printf("ADD:%s\r\n",fname);
  458.                 ++cfcb;
  459.                 if (cfcb < nfcb)
  460.                     size=bldentry(fname);
  461.                 }
  462.             else if (vc == 0) {
  463.                 putentry(obuffer,fname,volname,size);
  464.                 printf("CHG:%s\r\n",fname);
  465.                 ++cfcb;
  466.                 if (cfcb < nfcb)
  467.                     size=bldentry(fname);
  468.                 recsize = readline(ibuffer,rec);
  469.                 if (recsize > 0)
  470.                     rsize=extract(rfname,rvolname,
  471.                         rec);
  472.                 }
  473.             else /* (vc > 0) */ {
  474.                 putentry(obuffer,rfname,rvolname,rsize);
  475.                 recsize = readline(ibuffer,rec);
  476.                 if (recsize > 0)
  477.                     rsize=extract(rfname,rvolname,
  478.                         rec);
  479.                 }
  480.             }
  481.         else /* (fc > 0) */ {
  482.             if (vc == 0) {
  483.                 printf("DEL:%s\r\n",rfname);
  484.                 recsize = readline(ibuffer,rec);
  485.                 if (recsize > 0)
  486.                     rsize=extract(rfname,rvolname,
  487.                         rec);
  488.                 }
  489.             else    {
  490.                 putentry(obuffer,rfname,rvolname,rsize);
  491.                 recsize = readline(ibuffer,rec);
  492.                 if (recsize > 0)
  493.                     rsize=extract(rfname,rvolname,
  494.                         rec);
  495.                 }
  496.             }
  497.         }
  498.     if (recsize < 0)
  499.         while (cfcb < nfcb) {
  500.             putentry(obuffer,fname,volname,size);
  501.             printf("ADD:%s\r\n",fname);
  502.             cfcb++;
  503.             if (cfcb < nfcb)
  504.                 size = bldentry(fname);
  505.             }
  506.     if (cfcb == nfcb)
  507.         while (recsize >= 0) {
  508.             vc = strcmp(volname,rvolname);
  509.             if (vc == 0)
  510.                 printf("DEL:%s\r\n",rfname);
  511.             else
  512.                 putentry(obuffer,rfname,rvolname,rsize);
  513.             recsize = readline(ibuffer,rec);
  514.             if (recsize > 0)
  515.                 rsize=extract(rfname,rvolname,rec);
  516.             }
  517.     putc(CPMEOF,obuffer);
  518.     fflush(obuffer);
  519.     fclose(ibuffer);
  520.     fclose(obuffer);
  521.     hold();
  522. }
  523.  
  524. copydont(fdo,fdi)
  525. FILE *fdi,*fdo;
  526. {
  527.     char rec[GETS_SIZE];
  528.  
  529.     head = NULL;
  530.     if (readline(fdi,rec) < 0)
  531.         abort("\r\nFile MAST.CAT is null\r\n");
  532.     else if (rec[0] != '(')
  533.         abort("\r\nNo valid exclude files\r\n");
  534.     while (rec[strlen(rec)-1] != ')') {
  535.         writeline(fdo,rec);
  536.         dontadd(rec);
  537.         if (readline(fdi,rec) < 0)
  538.             abort("\r\nPremature End of File\r\n");
  539.         }
  540.     writeline(fdo,rec);
  541.     rec[strlen(rec)-1] = EOS;
  542.     dontadd(rec);
  543. }
  544.  
  545. dontadd(rec)
  546. char *rec;
  547. {
  548.     int i,j;
  549.     struct dontcat *ptr,*nptr;
  550.  
  551.     i=0;
  552.     if (rec[0] == '(')
  553.         i = 1;
  554.     nptr = ptr = head;
  555.     while (nptr != NULL) {
  556.         ptr = nptr;
  557.         nptr = ptr->next;
  558.         }
  559.     if (diff(nptr,ptr) == 0)
  560.         nptr = head = alloc(15);
  561.     else    nptr = ptr->next = alloc(15);
  562.     nptr->next = NULL;
  563.     j = 0;
  564.     while (j<8 && rec[i] != '.' && rec[i] != EOS)
  565.         nptr->fname[j++] = rec[i++];
  566.     while (j<8)
  567.         nptr->fname[j++] = ' ';
  568.     if (rec[i] == '.')
  569.         i++;
  570.     while (j<11 && rec[i] != EOS)
  571.         nptr->fname[j++] = rec[i++];
  572.     while (j<11)
  573.         nptr->fname[j++] = ' ';
  574.     nptr->fname[j] = EOS;
  575. }
  576.  
  577. writeline(fd,buff)
  578. FILE *fd;
  579. char *buff;
  580. {
  581.     char c;
  582.     char *cp;
  583.  
  584.     cp = buff;
  585.     while ((c = *cp++) != EOS)
  586.         putc(c,fd);
  587.     putc('\r',fd);
  588.     putc('\n',fd);
  589. }
  590.  
  591. readline(fd,buff)
  592. FILE *fd;
  593. char *buff;
  594. {
  595.     char *cp;
  596.     int c;
  597.  
  598.     for (cp = buff; (c=getc(fd)) != '\n' && c != CPMEOF; )
  599.         if (c != '\r') *cp++ = c;
  600.     *cp = '\0';
  601.     if (cp != buff)
  602.         return cp-buff;
  603.     else if (c != CPMEOF)
  604.         return 0;
  605.     else    return -1;
  606. }
  607.  
  608. bldfree(buff,n)
  609. char *buff;
  610. int n;
  611. {
  612.     char *cp;
  613.  
  614.     buff[5] = 'k';
  615.     buff[6] = ' ';
  616.     buff[7] = ' ';
  617.     buff[8] = 'F';
  618.     buff[9] = 'R';
  619.     buff[10] = 'E';
  620.     buff[11] = '0';     /* free space is always user 0 */
  621.     buff[12] = EOS;
  622.     cp = &buff[5];
  623.     do {    *--cp = n%10 + '0';
  624.         n = n/10;
  625.         } while (n != 0);
  626.     while (cp > buff)
  627.         *--cp = '+';
  628.     return n;
  629. }
  630.  
  631. bldentry(fname)
  632. char *fname;
  633. {
  634.     int i,j;
  635.     char *fcb;
  636.     struct dontcat *ptr;
  637.  
  638.     while (cfcb < nfcb) {
  639.         fcb = pfcb[cfcb];
  640.         for (j=0,i=1; i<12; j++,i++)
  641.             fname[j] = fcb[i];
  642.         fname[11] = EOS;
  643.         ptr = head;
  644.         while (ptr != NULL && strcmp(ptr,fname))
  645.             ptr = ptr->next;
  646.         if (ptr == NULL) {
  647.             fname[11] = fcb[0] + '0';
  648.             fname[12] = EOS;
  649.             return (*(fcb+12)*16+ *(fcb+15)/(8*block)*block
  650.                 + ((*(fcb+15)%(8*block)>0)*block));
  651.             }
  652.         else    cfcb++;
  653.         }
  654.     return 0;
  655. }
  656.  
  657. putentry(fd,name,vol,size)
  658. FILE *fd;
  659. char *name,*vol;
  660. int size;
  661. {
  662.     char c,s[10],*cp;
  663.  
  664.     putfcb(fd,name);
  665.     putc(',',fd);
  666.     putfcb(fd,vol);
  667.     sprintf(s,",%d",name[11] - '0');
  668.     cp = s;
  669.     while (c = *cp++)
  670.         putc(c,fd);
  671.     sprintf(s,",%dK",size);
  672.     cp = s;
  673.     while (c = *cp++)
  674.         putc(c,fd);
  675.     putc('\r',fd);
  676.     putc('\n',fd);
  677. }
  678.  
  679. putfcb(fd,name)
  680. FILE *fd;
  681. char *name;
  682. {
  683.     int i;
  684.  
  685.     for (i=0; i<8; i++) {
  686.         if (name[i] == ' ')
  687.             break;
  688.         putc(name[i],fd);
  689.         }
  690.     if (name[8] != ' ')
  691.         putc('.',fd);
  692.     for (i=8; i<11; i++) {
  693.         if (name[i] == ' ')
  694.             break;
  695.         putc(name[i],fd);
  696.         }
  697. }
  698.  
  699. extract(name,vol,rec)
  700. char *name,*vol,*rec;
  701. {
  702.     int i,j,n,size;
  703.  
  704.     i = j = 0;
  705.     while (j<8 && rec[i] != '.' && rec[i] != ',' && rec[i] != EOS)
  706.         name[j++] = rec[i++];
  707.     while (j<8)
  708.         name[j++] = ' ';
  709.     if (rec[i] == '.')
  710.         i++;
  711.     while (j<11 && rec[i] != ',' && rec[i] != EOS)
  712.         name[j++] = rec[i++];
  713.     while (j<11)
  714.         name[j++] = ' ';
  715.     if (rec[i] == ',')
  716.         i++;
  717.     j = 0;
  718.     while (j<8 && rec[i] != '.' && rec[i] != ',' && rec[i] != EOS)
  719.         vol[j++] = rec[i++];
  720.     while (j<8)
  721.         vol[j++] = ' ';
  722.     if (rec[i] == '.')
  723.         i++;
  724.     while (j<11 && rec[i] != ',' && rec[i] != EOS)
  725.         vol[j++] = rec[i++];
  726.     while (j<11)
  727.         vol[j++] = ' ';
  728.     vol[11] = EOS;
  729.     if (rec[i] == ',')
  730.         i++;
  731.     n = 0;
  732.     while (isdigit(rec[i]))
  733.         n = n*10 + (rec[i++] - '0');
  734.     while (!isdigit(rec[i]) && rec[i] != EOS)
  735.         i++;
  736.     name[11] = n + '0';
  737.     name[12] = EOS;
  738.     size = 0;
  739.     while (isdigit(rec[i]))
  740.         size = size*10 + (rec[i++] - '0');
  741.     return size;
  742. }
  743.  
  744. listmast(str)
  745. char *str;
  746. {
  747.     int size;
  748.     char c;
  749.     char hstr[GETS_SIZE],rec[GETS_SIZE];
  750.     char file[13],vol[13],nstr[13];
  751.     char buffer[BUFSIZ];
  752.  
  753.     expandstr(nstr,str);
  754.     strcpy(hstr,"FILES: ");
  755.     strcat(hstr,str);
  756.     bdos(RESETDISK,0);
  757.     bdos(SELDISK,(mdrive - 'A'));
  758.     bdos(SETDMA,DMADDR);
  759.     if (fopen("MAST.CAT",buffer) == ERROR) {
  760.         puts("Can't open MAST.CAT -- ");
  761.         hold();
  762.         return 0;
  763.         }
  764.     linecount = 99;
  765.     itemcount = 0;
  766.     do c=getc(buffer); while (c != ')' && c != CPMEOF);
  767.     do c=getc(buffer); while (c != '\n' && c != CPMEOF);
  768.     while (readline(buffer,rec) > 0) {
  769.         size = extract(file,vol,rec);
  770.         if (filecompare(file,nstr) == 0)
  771.             listentry(file,vol,size,hstr);
  772.         }
  773.     if (printer) {
  774.         bdos(LISTCHAR,'\r');
  775.         bdos(LISTCHAR,'\n');
  776.         }
  777.     fclose(buffer);
  778.     hold();
  779. }
  780.  
  781. listvol(str)
  782. char *str;
  783. {
  784.     int size;
  785.     char c;
  786.     char hstr[GETS_SIZE],rec[GETS_SIZE];
  787.     char file[13],vol[13],nstr[13];
  788.     char buffer[BUFSIZ];
  789.  
  790.     expandstr(nstr,str);
  791.     strcpy(hstr,"VOLUME: ");
  792.     strcat(hstr,str);
  793.     bdos(RESETDISK,0);
  794.     bdos(SELDISK,(mdrive - 'A'));
  795.     bdos(SETDMA,DMADDR);
  796.     if (fopen("MAST.CAT",ibuffer) == ERROR) {
  797.         puts("Can't open MAST.CAT -- ");
  798.         hold();
  799.         return 0;
  800.         }
  801.     linecount = 99;
  802.     itemcount = 0;
  803.     do c=getc(ibuffer); while (c != ')' && c != CPMEOF);
  804.     do c=getc(ibuffer); while (c != '\n' && c != CPMEOF);
  805.     while (readline(ibuffer,rec) > 0) {
  806.         size = extract(file,vol,rec);
  807.         if (filecompare(vol,nstr) == 0)
  808.             listentry(file,vol,size,hstr);
  809.         }
  810.     if (printer) {
  811.         bdos(LISTCHAR,'\r');
  812.         bdos(LISTCHAR,'\n');
  813.         }
  814.     fclose(ibuffer);
  815.     hold();
  816. }
  817.  
  818. expandstr(nstr,str)
  819. char *nstr,*str;
  820. {
  821.     int i,j;
  822.  
  823.     i = j = 0;
  824.     if (str[j] == '*') {
  825.         j++;
  826.         while (i<8)
  827.             nstr[i++] = '?';
  828.         }
  829.     else
  830.         while (i<8 && str[j] != '.' && str[j] != EOS)
  831.             nstr[i++] =str[j++];
  832.     while (i<8)
  833.         nstr[i++] = ' ';
  834.     if (str[j] == '.')
  835.         j++;
  836.     if (str[j] == '*')
  837.         while (i<11)
  838.             nstr[i++] = '?';
  839.     else
  840.         while (i<11 && str[j] != EOS)
  841.             nstr[i++] = str[j++];
  842.     while (i<11)
  843.         nstr[i++] = ' ';
  844.     nstr[11] = '?';
  845.     nstr[12] = EOS;
  846. }
  847.  
  848. filecompare(file,str)
  849. char *file,*str;
  850. {
  851.     int i,diff;
  852.  
  853.     for (i=0; i<strlen(file); i++) {
  854.         if (str[i] == '?')
  855.             diff = 0;
  856.         else
  857.             diff = file[i] - str[i];
  858.         if (diff)
  859.             break;
  860.         }
  861.     return diff;
  862. }
  863.  
  864. listentry(file,vol,size,str)
  865. char *file,*vol,*str;
  866. int size;
  867. {
  868.     int i,j,k;
  869.     char s[50],stemp[5];
  870.     char *pfile,*pvol;
  871.     
  872.     if (linecount > MAXLINES) {
  873.         printf("%s\r\n\n",str);
  874.         if (printer) {
  875.             bdos(LISTCHAR,FF);
  876.             for (i=0; i<5; i++)
  877.                 bdos(LISTCHAR,' ');
  878.             for (i=0; i<strlen(str); i++)
  879.                 bdos(LISTCHAR,str[i]);
  880.             bdos(LISTCHAR,'\r');
  881.             bdos(LISTCHAR,'\n');
  882.             bdos(LISTCHAR,'\n');
  883.             }
  884.         strcpy(s,
  885.             "       NAME            DISK        SIZE  | ");
  886.         printf("%s",s);
  887.         if (printer)
  888.             for (i=0; i<strlen(s); i++)
  889.                 bdos(LISTCHAR,s[i]);
  890.         strcpy(s,"  NAME            DISK        SIZE\r\n\n");
  891.         printf("%s",s);
  892.         if (printer)
  893.             for (i=0; i<strlen(s); i++)
  894.                 bdos(LISTCHAR,s[i]);
  895.         linecount = 4;
  896.         itemcount = 0;
  897.         }
  898.     itemcount++;
  899.     pfile = file;
  900.     pvol = vol;
  901.     k = 0;
  902.     s[k++] = file[11];
  903.     s[k++] = ':';
  904.     for (j=1; j<9; j++)
  905.         if (*pfile == ' ')
  906.             pfile++;
  907.         else    s[k++] = *pfile++;
  908.     if (*pfile != ' ')
  909.         s[k++] = '.';
  910.     for (j=9; j<12; j++)
  911.         if (*pfile == ' ')
  912.             pfile++;
  913.         else    s[k++] = *pfile++;
  914.     while (k<16)
  915.         s[k++] = ' ';
  916.     for (j=1; j<9; j++)
  917.         if (*pvol == ' ')
  918.             pvol++;
  919.         else    s[k++] = *pvol++;
  920.     if (*pvol != ' ')
  921.         s[k++] = '.';
  922.     for (j=9; j<12; j++)
  923.         if (*pvol == ' ')
  924.             pvol++;
  925.         else    s[k++] = *pvol++;
  926.     while (k<30)
  927.         s[k++] = ' ';
  928.     sprintf(stemp,"%d",size);
  929.     for (j=0; j<strlen(stemp); j++)
  930.         s[k++] = stemp[j];
  931.     s[k++] = 'K';
  932.     while (k < 35)
  933.         s[k++] = ' ';
  934.     s[k] = EOS;
  935.     if (itemcount % 2)
  936.         printf("     %s | ",s);
  937.     else {
  938.         printf("%s\r\n",s);
  939.         linecount++;
  940.         }
  941.     if (printer) {
  942.         if (itemcount % 2)
  943.             for (i=0; i<5; i++)
  944.                 bdos(LISTCHAR,' ');
  945.         for (i=0; i<strlen(s); i++)
  946.             bdos(LISTCHAR,s[i]);
  947.         if (itemcount % 2) {
  948.             bdos(LISTCHAR,' ');
  949.             bdos(LISTCHAR,'|');
  950.             bdos(LISTCHAR,' ');
  951.             }
  952.         else {
  953.             bdos(LISTCHAR,'\r');
  954.             bdos(LISTCHAR,'\n');
  955.             }
  956.         }
  957. }
  958.  
  959. initmast()
  960. {
  961.     char c,str[GETS_SIZE];
  962.     int i,n;
  963.  
  964.     bdos(RESETDISK,0);
  965.     bdos(SELDISK,(mdrive - 'A'));
  966.     bdos(SETDMA,DMADDR);
  967.     if (fopen("MAST.CAT",ibuffer) != ERROR)
  968.         while (1) {
  969.             printf("\r\nMAST.CAT already exists on %c:",
  970.                 mdrive);
  971.             printf(" shall I release it? (y/n) - ");
  972.             c = getchar();
  973.             if (c == 'y' || c == 'Y') {
  974.                 printf("\r\n");
  975.                 fclose(ibuffer);
  976.                 break;
  977.                 }
  978.             if (c == 'n' || c == 'N') {
  979.                 fclose(ibuffer);
  980.                 return;
  981.                 }
  982.             }
  983.     if (fcreat("MAST.CAT",obuffer) == ERROR)
  984.         abort("can't build MAST.CAT");
  985.     printf("\r\nEnter files to be EXCLUDED from the Master ");
  986.     printf("Catalog.\r\nUse a null file name to end entry.\r\n");
  987.     printf("There must be at least one EXCLUDE file.\r\n");
  988.     printf("If you wish no files to be excluded then ");
  989.     printf("enter a dummy file name.\r\n");
  990.     putc('(',obuffer);
  991.     n = 0;
  992.     while (1) {
  993.         printf("Enter EXCLUDE file - ");
  994.         gets(str);
  995.         if (strlen(str) == 0)
  996.             if (n == 0) {
  997.                 printf("\r\nmust be at least one ");
  998.                 printf("EXCLUDE file\r\n");
  999.                 }
  1000.             else    break;
  1001.         else {
  1002.             if (n != 0)
  1003.                 putw('\r\n',obuffer);
  1004.             n = n + 1;
  1005.             for (i=0; i<strlen(str); i++)
  1006.                 putc(toupper(str[i]),obuffer);
  1007.             }
  1008.         }
  1009.     putc(')',obuffer);
  1010.     putw('\r\n',obuffer);
  1011.     putc(CPMEOF,obuffer);
  1012.     fflush(obuffer);
  1013.     fclose(obuffer);
  1014. }
  1015.  
  1016. getstr(s)
  1017. char *s;
  1018. {
  1019.     int i;
  1020.  
  1021.     puts("Enter match string using wildcards --");
  1022.     puts("\n     '?' to match a single character");
  1023.     puts("     '*' to match whole file name or type");
  1024.     printf("\n\n          Enter string - ");
  1025.     gets(s);
  1026.     for (i=0; i<strlen(s); i++)
  1027.         s[i] = toupper(s[i]);
  1028. }
  1029.  
  1030. makedirfile()
  1031. {
  1032.     char buf[GETS_SIZE],buf2[GETS_SIZE];
  1033.     BOOLEAN notdone;
  1034.  
  1035.     notdone = YES;
  1036.     while (notdone) {
  1037.         printf("Enter volume name as a cp/m file name\r\n");
  1038.         printf(" -- don't forget to use a dash as the ");
  1039.         printf("first character  ");
  1040.         gets(buf);
  1041.         if (buf[1] == ':')
  1042.             if (toupper(buf[0]) != ddrive)
  1043.                 printf("invalid drive\r\n");
  1044.             else {
  1045.                 strcpy(buf2,buf);
  1046.                 notdone = NO;
  1047.                 }
  1048.         else {
  1049.             buf2[0] = ddrive;
  1050.             buf2[1] = ':';
  1051.             buf2[2] = EOS;
  1052.             strcat(buf2,buf);
  1053.             notdone = NO;
  1054.             }
  1055.         if (!notdone)
  1056.             if (strlen(buf2) > 14) {
  1057.                 printf("file name too long\r\n");
  1058.                 notdone = YES;
  1059.                 }
  1060.         }
  1061.     bldfile(buf2);
  1062. }
  1063.  
  1064. bldfile(buf)
  1065. char *buf;
  1066. {
  1067.     char str[GETS_SIZE];
  1068.  
  1069.     if(fcreat(buf,obuffer) == ERROR) {
  1070.         sprintf(str,"unable to build file %s\r\n",buf);
  1071.         abort(str);
  1072.         }
  1073.     fclose(obuffer);    /* an empty file has now been built */
  1074.     puts("Volume label file built");
  1075. }
  1076.  
  1077. getdefaults()
  1078. {
  1079.     char c;
  1080.  
  1081.     do {
  1082.     printf("\r\nEnter drive where Master Catalog will reside - ");
  1083.     mdrive = toupper(getchar());
  1084.     } while ( mdrive < 'A' || mdrive >= (NUMDRIVES+'@'));
  1085.     do {
  1086.     printf("\r\nEnter drive of Disk to be cataloged - ");
  1087.     ddrive = toupper(getchar());
  1088.     } while ( ddrive < 'A' || ddrive >= (NUMDRIVES+'@'));
  1089.     do {
  1090.     printf("\r\nEcho displays to the CP/M list device? (y/n) - ");
  1091.     c = toupper(getchar());
  1092.     } while (c != 'Y' && c != 'N');
  1093.     if (c == 'Y')
  1094.     printer = YES;
  1095.     else
  1096.     printer = NO;
  1097. }
  1098.  
  1099. hold()
  1100. {
  1101.     printf("Press <return> to continue ");
  1102.     while(bdos(6,255) != CR) /* do nothing */ ;
  1103.     printf("\r\n");
  1104. }
  1105.  
  1106. abort(str)
  1107. char *str;
  1108. {
  1109.     printf("%s",str);
  1110.     printf("\r\n ----- aborting -----\r\n");
  1111.     exit();
  1112. }
  1113.  
  1114. diff(p1,p2)
  1115. char *p1,*p2;
  1116. {
  1117.     return p1-p2;
  1118. }
  1119.  
  1120. #include "v200.l"
  1121.